#include "IPC_Client_IFlash.h"
#include "g_qspi.h"
#include "gkt_config.h"

#if defined(GKT_CONFIG_FPS_ENABLE) && GKT_CONFIG_FPS_ENABLE

extern const uint32_t gkt_template_addr_start;
extern const uint32_t gkt_template_addr_end;

extern G_IpcInitTypeDef  IpcParaInit;
const G_Client_IFlash_Func_TyperDef IpcCliIFlashCmd[] =
{
    G_Ipc_Client_IFlashSectorerase,
    G_Ipc_Client_IFlashRead,
    G_Ipc_Client_IFlashWrite,
    G_Ipc_Client_EncIFlashSectorerase32k,
    G_Ipc_Client_EncIFlashSectorerase32Byte,
    G_Ipc_Client_EncIFlashWrite,
    G_Ipc_Client_EncIFlashRead,
    G_Ipc_Client_EncIFlashWrite32k,
    G_Ipc_Client_FlashBlankCheck,
    G_Ipc_Client_EncIFlashRead_fast,
};

G_IpcStatusTypeDef G_Client_IFlashisEnd(void)
{
	IpcParaInit.Ipc_IflashParaCB.IflashEndStatus = TRUE;
    return IPC_SUCCESS;
}

void G_Client_WaitIFlashReady(void)
{
    while(IpcParaInit.Ipc_IflashParaCB.IflashReadyStatus!=TRUE);
}

static uint32_t gkt_ipc_flash_addr_check(void)
{
	if((IpcParaInit.Ipc_IflashParaCB.IflashAddr >= gkt_template_addr_start)	\
		&&(IpcParaInit.Ipc_IflashParaCB.IflashAddr < gkt_template_addr_end)){
		return 1;
	}
	else
		return 0;
}

G_IpcStatusTypeDef G_Ipc_Client_IFlashSectorerase(uint8_t *pdata)
{
    G_Client_System_Cmd_Sync_Send();
    G_Client_WaitIFlashReady();
    IPC_DEBUG_LOG(IPC_DEBUG_CLIENT_IFLASH, ("IFlashSectorerase[%x]\n",IpcParaInit.Ipc_IflashParaCB.IflashAddr));
	if(gkt_ipc_flash_addr_check()){
    	IpcParaInit.Ipc_IflashParaCB.IflashRet=G_qspi_flash_sectorerase(IpcParaInit.Ipc_IflashParaCB.IflashAddr);
	}
	else{
		IpcParaInit.Ipc_IflashParaCB.IflashRet = ERROR;
	}
    IPC_DEBUG_LOG(IPC_DEBUG_CLIENT_IFLASH, ("IFlashSectorerase end[%d]\n",IpcParaInit.Ipc_IflashParaCB.IflashRet));
    G_Client_IFlashisEnd();
    return IPC_SUCCESS;
}

G_IpcStatusTypeDef G_Ipc_Client_IFlashRead(uint8_t *pdata)
{
    G_Client_System_Cmd_Sync_Send();
    G_Client_WaitIFlashReady();
    IPC_DEBUG_LOG(IPC_DEBUG_CLIENT_IFLASH, ("IFlashRead[%x]\n",IpcParaInit.Ipc_IflashParaCB.IflashAddr));
	if(gkt_ipc_flash_addr_check()){
    	IpcParaInit.Ipc_IflashParaCB.IflashRet=G_qspi_flash_read(IpcParaInit.Ipc_IflashParaCB.IflashAddr,(uint8_t *)IpcParaInit.Ipc_IflashParaCB.IflashBufferAddr,IpcParaInit.Ipc_IflashParaCB.IflashwrSize);
	}
	else{
		IpcParaInit.Ipc_IflashParaCB.IflashRet = ERROR;
	}
    IPC_DEBUG_LOG(IPC_DEBUG_CLIENT_IFLASH, ("IFlashRead end[%d]\n",IpcParaInit.Ipc_IflashParaCB.IflashRet));
    G_Client_IFlashisEnd();
    return IPC_SUCCESS;
}

G_IpcStatusTypeDef G_Ipc_Client_IFlashWrite(uint8_t *pdata)
{
    G_Client_System_Cmd_Sync_Send();
    G_Client_WaitIFlashReady();
    IPC_DEBUG_LOG(IPC_DEBUG_CLIENT_IFLASH, ("IFlashWrite[%x]\n",IpcParaInit.Ipc_IflashParaCB.IflashAddr));
	if(gkt_ipc_flash_addr_check()){
    	IpcParaInit.Ipc_IflashParaCB.IflashRet=G_qspi_flash_write(IpcParaInit.Ipc_IflashParaCB.IflashAddr,(uint8_t *)IpcParaInit.Ipc_IflashParaCB.IflashBufferAddr,IpcParaInit.Ipc_IflashParaCB.IflashwrSize);
	}
	else{
		IpcParaInit.Ipc_IflashParaCB.IflashRet = ERROR;
	}
	IPC_DEBUG_LOG(IPC_DEBUG_CLIENT_IFLASH, ("IFlashWrite end[%d]\n",IpcParaInit.Ipc_IflashParaCB.IflashRet));
    G_Client_IFlashisEnd();
    return IPC_SUCCESS;
}

G_IpcStatusTypeDef G_Ipc_Client_EncIFlashSectorerase32k(uint8_t *pdata)
{
    G_Client_System_Cmd_Sync_Send();
    G_Client_WaitIFlashReady();
    IPC_DEBUG_LOG(IPC_DEBUG_CLIENT_IFLASH, ("EncIFlashSectorerase32k[%x]\n",IpcParaInit.Ipc_IflashParaCB.IflashAddr));
	if(gkt_ipc_flash_addr_check()){
    	IpcParaInit.Ipc_IflashParaCB.IflashRet=G_enc_erase_flash_32k(IpcParaInit.Ipc_IflashParaCB.IflashAddr);
	}
	else{
		IpcParaInit.Ipc_IflashParaCB.IflashRet = ERROR;
	}
    IPC_DEBUG_LOG(IPC_DEBUG_CLIENT_IFLASH, ("EncIFlashSectorerase32k end[%d]\n",IpcParaInit.Ipc_IflashParaCB.IflashRet));
    G_Client_IFlashisEnd();
    return IPC_SUCCESS;
}

G_IpcStatusTypeDef G_Ipc_Client_EncIFlashSectorerase32Byte(uint8_t *pdata)
{
    G_Client_System_Cmd_Sync_Send();
    G_Client_WaitIFlashReady();
    IPC_DEBUG_LOG(IPC_DEBUG_CLIENT_IFLASH, ("EncIFlashSectorerase32Byte[%x]\n",IpcParaInit.Ipc_IflashParaCB.IflashAddr));
	if(gkt_ipc_flash_addr_check()){
    	IpcParaInit.Ipc_IflashParaCB.IflashRet=G_enc_erase_flash_32byte(IpcParaInit.Ipc_IflashParaCB.IflashAddr);
	}
	else{
		IpcParaInit.Ipc_IflashParaCB.IflashRet = ERROR;
	}
    IPC_DEBUG_LOG(IPC_DEBUG_CLIENT_IFLASH, ("EncIFlashSectorerase32Byte end[%d]\n",IpcParaInit.Ipc_IflashParaCB.IflashRet));
    G_Client_IFlashisEnd();
    return IPC_SUCCESS;
}

G_IpcStatusTypeDef G_Ipc_Client_EncIFlashWrite(uint8_t *pdata)
{
    G_Client_System_Cmd_Sync_Send();
    G_Client_WaitIFlashReady();
    IPC_DEBUG_LOG(IPC_DEBUG_CLIENT_IFLASH, ("EncIFlashWrite[%x]\n",IpcParaInit.Ipc_IflashParaCB.IflashAddr));
	if(gkt_ipc_flash_addr_check()){
    	IpcParaInit.Ipc_IflashParaCB.IflashRet=G_enc_write_flash(IpcParaInit.Ipc_IflashParaCB.IflashAddr,(uint8_t *)IpcParaInit.Ipc_IflashParaCB.IflashBufferAddr,IpcParaInit.Ipc_IflashParaCB.IflashwrSize);
	}
	else{
		IpcParaInit.Ipc_IflashParaCB.IflashRet = ERROR;
	}
	IPC_DEBUG_LOG(IPC_DEBUG_CLIENT_IFLASH, ("EncIFlashWrite end[%d]\n",IpcParaInit.Ipc_IflashParaCB.IflashRet));
    G_Client_IFlashisEnd();
    return IPC_SUCCESS;
}

G_IpcStatusTypeDef G_Ipc_Client_EncIFlashRead(uint8_t *pdata)
{
    G_Client_System_Cmd_Sync_Send();
    G_Client_WaitIFlashReady();
    IPC_DEBUG_LOG(IPC_DEBUG_CLIENT_IFLASH, ("EncIFlashRead[%x]\n",IpcParaInit.Ipc_IflashParaCB.IflashAddr));
	if(gkt_ipc_flash_addr_check()){
    	IpcParaInit.Ipc_IflashParaCB.IflashRet=G_enc_read_flash(IpcParaInit.Ipc_IflashParaCB.IflashAddr,(uint8_t *)IpcParaInit.Ipc_IflashParaCB.IflashBufferAddr,IpcParaInit.Ipc_IflashParaCB.IflashwrSize);
	}
	else{
		IpcParaInit.Ipc_IflashParaCB.IflashRet = ERROR;
	}
	IPC_DEBUG_LOG(IPC_DEBUG_CLIENT_IFLASH, ("EncIFlashRead end[%d]\n",IpcParaInit.Ipc_IflashParaCB.IflashRet));
    G_Client_IFlashisEnd();
    return IPC_SUCCESS;
}

G_IpcStatusTypeDef G_Ipc_Client_EncIFlashWrite32k(uint8_t *pdata)
{
    G_Client_System_Cmd_Sync_Send();
    G_Client_WaitIFlashReady();
    G_ENC_BulkTypeDef enc_bulk_struct;
    enc_bulk_struct.enc_index=0;
    enc_bulk_struct.is_end=1;//Write 32k at once
    IPC_DEBUG_LOG(IPC_DEBUG_CLIENT_IFLASH, ("EncIFlashWrite32k[%x]\n",IpcParaInit.Ipc_IflashParaCB.IflashAddr));
	if(gkt_ipc_flash_addr_check()){
    	IpcParaInit.Ipc_IflashParaCB.IflashRet=G_enc_write_flash_bulk(&enc_bulk_struct,IpcParaInit.Ipc_IflashParaCB.IflashAddr,(uint8_t *)IpcParaInit.Ipc_IflashParaCB.IflashBufferAddr,IpcParaInit.Ipc_IflashParaCB.IflashwrSize);
	}
	else{
		IpcParaInit.Ipc_IflashParaCB.IflashRet = ERROR;
	}
	IPC_DEBUG_LOG(IPC_DEBUG_CLIENT_IFLASH, ("EncIFlashWrite32k end[%d]\n",IpcParaInit.Ipc_IflashParaCB.IflashRet));
    G_Client_IFlashisEnd();
    return IPC_SUCCESS;
}


G_IpcStatusTypeDef G_Ipc_Client_FlashBlankCheck(uint8_t *pdata)
{
    G_Client_System_Cmd_Sync_Send();
    G_Client_WaitIFlashReady();
    IPC_DEBUG_LOG(IPC_DEBUG_CLIENT_IFLASH, ("FlashBlankCheck[%x]\n",IpcParaInit.Ipc_IflashParaCB.IflashAddr));
    if(FALSE==G_flash_blank_check(IpcParaInit.Ipc_IflashParaCB.IflashAddr,IpcParaInit.Ipc_IflashParaCB.IflashwrSize))
    {
        IpcParaInit.Ipc_IflashParaCB.IflashRet=SUCCESS;
    }
    else
    {
        IpcParaInit.Ipc_IflashParaCB.IflashRet=ERROR;
    }
    IPC_DEBUG_LOG(IPC_DEBUG_CLIENT_IFLASH, ("FlashBlankCheck end[%d]\n",IpcParaInit.Ipc_IflashParaCB.IflashRet));
    G_Client_IFlashisEnd();
    return IPC_SUCCESS;
}

G_IpcStatusTypeDef G_Ipc_Client_EncIFlashRead_fast(uint8_t *pdata)
{
    G_Client_System_Cmd_Sync_Send();
    G_Client_WaitIFlashReady();
    IPC_DEBUG_LOG(IPC_DEBUG_CLIENT_IFLASH, ("EncIFlashRead_fast[%x]\n",IpcParaInit.Ipc_IflashParaCB.IflashAddr));
	if(gkt_ipc_flash_addr_check()){
   		IpcParaInit.Ipc_IflashParaCB.IflashRet=G_enc_read_flash_fast(IpcParaInit.Ipc_IflashParaCB.IflashAddr,(uint8_t *)IpcParaInit.Ipc_IflashParaCB.IflashBufferAddr,IpcParaInit.Ipc_IflashParaCB.IflashwrSize);
	}
	else{
		IpcParaInit.Ipc_IflashParaCB.IflashRet = ERROR;
	}
	IPC_DEBUG_LOG(IPC_DEBUG_CLIENT_IFLASH, ("EncIFlashRead_fast end[%d]\n",IpcParaInit.Ipc_IflashParaCB.IflashRet));
    G_Client_IFlashisEnd();
    return IPC_SUCCESS;
}

#endif

